package com.lute.model;

import java.util.ArrayList;
import java.util.GregorianCalendar;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;

import org.hibernate.HibernateException;
import org.springframework.security.oauth2.common.json.JSONException;
import org.springframework.security.oauth2.common.json.JSONObject;

import com.lute.utils.DAOFactory;
import com.lute.utils.ServerErrorResponse;

@Entity
public class ClientAccountingPeriod {

	private int id_client_accounting_period;
	private Client client;
	private String clientAccountingPeriodState; //open, closed
	private List<EmployeeAccountingPeriod> employeeAccountingPeriod = new ArrayList<EmployeeAccountingPeriod>();
	private GregorianCalendar from;
	private GregorianCalendar to;
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	public int getId_client_accounting_period() {
		return id_client_accounting_period;
	}
	public void setId_client_accounting_period(int id_client_accounting_period) {
		this.id_client_accounting_period = id_client_accounting_period;
	}
	public GregorianCalendar getDate_from() {
		return from;
	}
	public void setDate_from(GregorianCalendar date_from) {
		this.from = date_from;
	}
	public GregorianCalendar getDate_to() {
		return to;
	}
	public void setDate_to(GregorianCalendar date_to) {
		this.to = date_to;
	}
	
	@ManyToOne
	@JoinColumn(name="id_client")
	public Client getClient() {
		return client;
	}
	public void setClient(Client client) {
		this.client = client;
	}
	
	@OneToMany(targetEntity=EmployeeAccountingPeriod.class, mappedBy="clientAccountingPeriod",
			cascade=CascadeType.ALL, fetch=FetchType.LAZY)
	public List<EmployeeAccountingPeriod> getEmployeeAccountingPeriod() {
		return employeeAccountingPeriod;
	}
	public void setEmployeeAccountingPeriod(
			List<EmployeeAccountingPeriod> employeeAccountingPeriod) {
		this.employeeAccountingPeriod = employeeAccountingPeriod;
	}
	
	public String getClientAccountingPeriodState() {
		return clientAccountingPeriodState;
	}
	
	public void setClientAccountingPeriodState(String clientAccountingPeriodState) {
		this.clientAccountingPeriodState = clientAccountingPeriodState;
	}
	
	public static ClientAccountingPeriod getClientCurrentAccountinPeriod(int id_client, JSONObject jsonRes) throws JSONException {
		ClientAccountingPeriod clientAccountingPeriod = null;
		try {
			return DAOFactory.getInstance().getLuteInterface().getClientCurrentAccountingPeriodFromDataBase("client.id", id_client);
		} catch(HibernateException e) {
			jsonRes.put("result", ServerErrorResponse.INTERNAL_ERROR.toString());
		}
		return clientAccountingPeriod;
	}
	
	public static ClientAccountingPeriod getClientCurrentAccountinPeriodWithEmployeeAccPeriods(int id_client) {
		ClientAccountingPeriod clientAccountingPeriod = null;
		Client client = Client.getClientWithClientAccPeriodByIdFromDB("id_client", id_client);
		List<ClientAccountingPeriod> clientPeriods = client.getClientAccountingPeriods();
		for(ClientAccountingPeriod period : clientPeriods) {
			if(period.getClientAccountingPeriodState().equals(ClientAccountingPeriodState.OPEN.toString())) {
				clientAccountingPeriod = ClientAccountingPeriod.
						getClientAccountingPeriodWithEmployeeAccPeriodsByIdFromDB
									("id_client_accounting_period", period.getId_client_accounting_period());
				return clientAccountingPeriod;
			}
		}
		return clientAccountingPeriod;
	}
	
	public static void closeAccountingPeriod(ClientAccountingPeriod period) {
		period.setClientAccountingPeriodState(ClientAccountingPeriodState.CLOSE.toString());
	}
	
	public static ClientAccountingPeriod getClientAccountingPeriodByIdFromDB(String propertyValue, int propertyName) {
		return DAOFactory.getInstance().getLuteInterface().getClientAccountingPeriodByIdFromDataBase(propertyValue, propertyName);
	}
	
	public static ClientAccountingPeriod getClientAccountingPeriodWithEmployeeAccPeriodsByIdFromDB(String propertyValue, int propertyName) {
		return DAOFactory.getInstance().getLuteInterface().
				getClientAccountingPeriodWithEmployeeAccPeriodsByIdFromDataBase("id_client_accounting_period", propertyName);
	}
	
	public static ClientAccountingPeriod getClientAccountingPeriodWithEmployeeAccPeriodsBySpecifiedClientFromDB(String propertyName1, int id_client,
																												String propertyName2, GregorianCalendar from) {
		return DAOFactory.getInstance().getLuteInterface().
				getClientAccountingPeriodWithEmployeeAccPeriodsBySpecifiedClientFromDataBase(propertyName1, id_client, propertyName2, from);
	}
	
	public static void addClientAccountingPeriodToDB(ClientAccountingPeriod period) {
		DAOFactory.getInstance().getLuteInterface().addObjectToDataBase(period);
	}
	
	public static void addClientAccountingPeriodsToDB(List<ClientAccountingPeriod> periods) {
		DAOFactory.getInstance().getLuteInterface().addObjectToDataBase(periods);
	}
	
	public static void updateClientAccountingPeriodsInDB(ClientAccountingPeriod period) {
		DAOFactory.getInstance().getLuteInterface().updateObjectinDataBase(period);
	}
}
